package com.zebra.common.concurrent;

import com.lmax.disruptor.EventTranslatorOneArg;
import com.lmax.disruptor.dsl.Disruptor;

import java.util.concurrent.Executor;

/**
 *
 * @Date 2020/2/29 0029
 **/
public class ZebraExecutor implements Executor {

    private static final int BUFFER_SIZE = 1024;
    private static final String FACTORY_NAME = "zebra-dis";
    private final Disruptor<ZebraTaskEvent> disruptor;

    private EventTranslatorOneArg<ZebraTaskEvent, Runnable> eventTranslatorOneArg;

    public ZebraExecutor() {
        this(BUFFER_SIZE, FACTORY_NAME);
    }

    public ZebraExecutor(int size) {
        this(size, FACTORY_NAME);
    }

    public ZebraExecutor(int size, String name) {
//    this.disruptor = new Disruptor<>(ZebraTaskEvent::new, BUFFER_SIZE, DaemonThreadFactory.INSTANCE, ProducerType.MULTI, new YieldingWaitStrategy());
        this.disruptor = new Disruptor<>(ZebraTaskEvent::new, size, new ZebraThreadFactory(name));
    }


    public void start() {
        this.eventTranslatorOneArg = (event, sequence, data) -> event.setTask(data);
        disruptor.setDefaultExceptionHandler(new ZebraLogExceptionHandler());
        disruptor.handleEventsWith((event, sequence, endOfBatch) -> event.getTask().run());
        disruptor.start();
    }

    @Override
    public void execute(Runnable task) {
        disruptor.getRingBuffer().publishEvent(eventTranslatorOneArg, task);
    }


    public void shutdown() {
        disruptor.shutdown();
    }


    public void halt() {
        disruptor.halt();
    }


}


